package yunjiao.javatutorials.mq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import yunjiao.javatutorials.mq.model.MqTopicEnum;

import java.util.ArrayList;
import java.util.List;


/**
 * MQ 配置类
 *
 * @author yangyunjiao
 */
@Slf4j
@Configuration
public class RabbitMqConfig {
    // ========== 1. 声明交换机+队列+绑定关系（所有主题统一配置） ==========
    @Bean
    public Declarables mqDeclarables() {
        List<Declarable> allDeclarables = new ArrayList<>();
        // 遍历所有主题，创建持久化交换机+队列+绑定
        for (MqTopicEnum topic : MqTopicEnum.values()) {
            // 交换机（Direct类型：精准路由，适合点对点同步）
            DirectExchange exchange = new DirectExchange(
                    topic.getExchange(),
                    true,  // 持久化（MQ重启不丢失）
                    false  // 不自动删除
            );

            // 队列（持久化+非独占+不自动删除）
            Queue queue = QueueBuilder.durable(topic.getQueue()).build();

            // 绑定（交换机+路由键+队列）
            Binding binding = BindingBuilder.bind(queue)
                    .to(exchange)
                    .with(topic.getRoutingKey());

            allDeclarables.add(exchange);
            allDeclarables.add(queue);
            allDeclarables.add(binding);
        }
        Declarables bean = new Declarables(allDeclarables);
        log.info(">>>> Declarables : {}", bean);
        return bean;
    }

    // ========== 2. 消息序列化（JSON格式，支持复杂对象） ==========
    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter() {
        Jackson2JsonMessageConverter bean = new Jackson2JsonMessageConverter();
        log.info(">>>> Jackson2JsonMessageConverter : {}", bean);
        return bean;
    }

    // ========== 3. RabbitTemplate配置（发送端核心工具） ==========
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter()); // 序列化方式
        rabbitTemplate.setMandatory(true); // 消息必须路由到队列，否则触发回调
        // 消息发送确认回调（可选：记录发送状态）
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                String msgId = correlationData.getId();
                // log.info("消息发送成功：messageId={}", msgId);
            } else {
                // log.error("消息发送失败：cause={}", cause);
            }
        });

        log.info(">>>> RabbitTemplate : {}", rabbitTemplate);
        return rabbitTemplate;
    }
}
